package com.sali.asyncollection.controller.asyn_request_merge;

import cn.hutool.json.JSONObject;
import com.sali.asyncollection.model.*;
import com.sali.asyncollection.service.ExecuteTaskService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @description:
 * @author: sali
 * @date: 2024/8/27 下午8:10.
 * @version: 1.0
 */
@RequestMapping("/admin/v1")
@RestController
@Slf4j
public class TestParallelApi02Controller {


    @GetMapping("/parallel/02")
    public JSONObject parallelController02() {
        long beginTime = System.currentTimeMillis();
        System.out.println("开始并行查询app首页信息");
        //用户信息查询任务
        Callable<BaseRspDTO<Object>> userInfoDTOCallableTask = () -> {
            UserInfoParam userInfoParam = new UserInfoParam("我是userInfoParameter");
            UserInfoDTO userInfoDTO = getUserInfo(userInfoParam);
            BaseRspDTO<Object> userBaseRspDTO = new BaseRspDTO<Object>();
            userBaseRspDTO.setKey("userInfoDTO");
            userBaseRspDTO.setData(userInfoDTO);
            return userBaseRspDTO;
        };

        //banner信息查询任务
        Callable<BaseRspDTO<Object>> bannerDTOCallableTask = () -> {
            BannerParam bannerParam = new BannerParam("我是bannerParameter");
            BannerDTO bannerDTO = getBannerInfo(bannerParam);
            BaseRspDTO<Object> bannerBaseRspDTO = new BaseRspDTO<Object>();
            bannerBaseRspDTO.setKey("bannerDTO");
            bannerBaseRspDTO.setData(bannerDTO);
            return bannerBaseRspDTO;
        };

        //label信息查询任务
        Callable<BaseRspDTO<Object>> labelDTODTOCallableTask = () -> {
            LabelParam labelParam = new LabelParam("我是labelParameter");
            LabelDTO labelDTO = getLabelInfo(labelParam);
            BaseRspDTO<Object> labelBaseRspDTO = new BaseRspDTO<Object>();
            labelBaseRspDTO.setKey("labelDTO");
            labelBaseRspDTO.setData(labelDTO);
            return labelBaseRspDTO;
        };

        List<Callable<BaseRspDTO<Object>>> taskList = new ArrayList<>();
        taskList.add(userInfoDTOCallableTask);
        taskList.add(bannerDTOCallableTask);
        taskList.add(labelDTODTOCallableTask);
        ExecutorService executor = Executors.newFixedThreadPool(10);
        List<BaseRspDTO<Object>> resultList = ExecuteTaskService.executeTask(taskList, 3, executor);
        if (resultList.isEmpty()) {
            log.error("任务执行出错");
            return null;
        }

        UserInfoDTO userInfoDTO = null;
        BannerDTO bannerDTO = null;
        LabelDTO labelDTO = null;

        //遍历结果
        for (int i = 0; i < resultList.size(); i++) {
            BaseRspDTO baseRspDTO = resultList.get(i);
            if ("userInfoDTO".equals(baseRspDTO.getKey())) {
                userInfoDTO = (UserInfoDTO) baseRspDTO.getData();
            } else if ("bannerDTO".equals(baseRspDTO.getKey())) {
                bannerDTO = (BannerDTO) baseRspDTO.getData();
            } else if ("labelDTO".equals(baseRspDTO.getKey())) {
                labelDTO = (LabelDTO) baseRspDTO.getData();
            }
        }

        System.out.println("结束并行查询app首页信息,总耗时：" + (System.currentTimeMillis() - beginTime));
        JSONObject result = new JSONObject();
        result.put("userInfoDTO", userInfoDTO);
        result.put("bannerDTO", bannerDTO);
        result.put("labelDTO", labelDTO);
        return result;
    }


    private static UserInfoDTO getUserInfo(UserInfoParam userInfoParam) {
        try {
            log.info("getUserInfo正在执行...，接收参数: {}", userInfoParam);
            Thread.sleep(100);
        } catch (InterruptedException ignored) {
        }
        return UserInfoDTO.builder().id(1L).username("username-A").build();
    }

    private static BannerDTO getBannerInfo(BannerParam bannerParam) {
        try {
            log.info("getBannerInfo正在执行...，接收参数：{}", bannerParam);
            Thread.sleep(200);
        } catch (InterruptedException ignored) {
        }
        return BannerDTO.builder().id(1L).bannername("bannername-A").build();
    }

    private static LabelDTO getLabelInfo(LabelParam labelParam) {
        try {
            log.info("getLabelInfo正在执行...，接收参数：{}", labelParam);
            Thread.sleep(300);
        } catch (InterruptedException ignored) {
        }
        return LabelDTO.builder().id(1L).labelname("labelname-A").build();
    }
}
